//
//  BRSXMLRequestOperation.m
//  Pint
//
//  Created by xiect on 13-10-25.
//  Copyright (c) 2013年 brains. All rights reserved.
//

#import "BRSXMLRequestOperation.h"
#import "BRSAppDelegate.h"
#import "Utils.h"
#import "BRSError.h"

static dispatch_queue_t gdata_request_operation_processing_queue() {
    static dispatch_queue_t brs_gdata_request_operation_processing_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        brs_gdata_request_operation_processing_queue = dispatch_queue_create("com.brains.networking.xml-request.processing", DISPATCH_QUEUE_CONCURRENT);
    });
    return brs_gdata_request_operation_processing_queue;
}
@interface BRSXMLRequestOperation ()
@property (readwrite, nonatomic, strong) id responseXMLDocument;
@property (readwrite, nonatomic, strong) NSError *XMLError;
@property (readwrite, nonatomic, strong) NSRecursiveLock *lock;
@end

@implementation BRSXMLRequestOperation


+ (NSSet *)acceptableContentTypes {
    return [NSSet setWithObjects:@"application/xml", @"text/xml", nil];
}

+ (BOOL)canProcessRequest:(NSURLRequest *)request {
    return [[[request URL] pathExtension] isEqualToString:@"xml"] || [super canProcessRequest:request];
}

- (id)responseXMLDocument {
    [self.lock lock];
    if (!_responseXMLDocument && [self.responseData length] > 0 && [self isFinished] && !self.XMLError) {
        NSError *error = nil;
        if (self.responseString && ![self.responseString isEqualToString:@" "]) {
            NSData *data = [self.responseString dataUsingEncoding:NSUTF8StringEncoding];
            
            if (data) {
                self.responseXMLDocument = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];
            } else {
                // TODO ERROR INFO
                NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
                [userInfo setValue:@"Operation responseData failed decoding as a UTF-8 string" forKey:NSLocalizedDescriptionKey];
                [userInfo setValue:[NSString stringWithFormat:@"Could not decode string: %@", self.responseString] forKey:NSLocalizedFailureReasonErrorKey];
                error = [[NSError alloc] initWithDomain:AFNetworkingErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo];
            }
        }
        self.XMLError = error;
    }
    [self.lock unlock];
    return _responseXMLDocument;
}

- (NSError *)error {
    if (_XMLError) {
        return _XMLError;
    } else {
        return [super error];
    }
}

- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                              failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles"
#pragma clang diagnostic ignored "-Wgnu"
    self.completionBlock = ^{
        
        if (self.error) {
            NSLog(@"ERROR CODE %d",self.error.code);
            if (failure) {
                // カスータムエラーオブッジェトへ変更
                BRSError *pintError = [[BRSError alloc] initWithDomain:kBusinessErrorDomain code:[self.error code] userInfo:[self.error userInfo]];
                dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                    failure(self, pintError);
                });
            }
        } else {
            dispatch_async(gdata_request_operation_processing_queue(), ^{
                id xmlDocument = self.responseXMLDocument;
                // TODO SOAP STATUS　判断
                if (self.error) {
                    if (failure) {
                        // カスータムエラーオブッジェトへ変更
                        BRSError *tempError = [[BRSError alloc] initWithDomain:kBusinessErrorDomain code:[self.error code] userInfo:[self.error userInfo]];
                        dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                            failure(self, tempError);
                        });
                    }
                } else {
                    if (success) {
                        dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
                            success(self, xmlDocument);
                        });
                    }
                }
            });
        }
    };
#pragma clang diagnostic pop
}
@end
